package com.alks.function.service.impl.biocontrol.deptwork;

import com.alks.common.data.thread.UserIdThread;
import com.alks.common.utils.beanutils.ArrayUtils;
import com.alks.entity.data.entity.CpCutInfo;
import com.alks.entity.data.entity.CpCutPart;
import com.alks.entity.data.entity.CpCutStyle;
import com.alks.entity.data.entity.SdStyle;
import com.alks.entity.data.response.ResponseInfo;
import com.alks.entity.exception.ServiceErrorException;
import com.alks.function.mapper.SdStyleMapper;
import com.alks.function.mapper.biocontrol.deptwork.BC_DW_CpCutInfoMapper;
import com.alks.function.mapper.biocontrol.deptwork.BC_DW_CpCutPartMapper;
import com.alks.function.mapper.biocontrol.deptwork.BC_DW_CpCutStyleMapper;
import com.alks.function.service.biocontrol.deptwork.ICpCutService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.sql.SQLIntegrityConstraintViolationException;
import java.util.*;
import java.util.stream.Collectors;

import static com.alks.entity.data.enums.ResultCodeEnum.INPUT_ERROR;

@Service
@Slf4j
@RequiredArgsConstructor
public class CpCutServiceImpl extends ServiceImpl<BC_DW_CpCutPartMapper, CpCutPart> implements ICpCutService {
    private final BC_DW_CpCutInfoMapper infoMapper;
    private final BC_DW_CpCutPartMapper partMapper;
    private final BC_DW_CpCutStyleMapper styleMapper;
    private final SdStyleMapper sdStyleMapper;

    @Override
    public ResponseInfo getCpCutQuery(String style) {
        /*获取数据*/
        List<Map<String, String>> dtos = infoMapper.getCpCutQuery(style, UserIdThread.get().getCompanyId());
        return ResponseInfo.ok(dtos);
    }

    @Override
    public ResponseInfo cpCutAdd(CpCutInfo request) {
        /*入参检测*/
        if (request.getCutNo() == null || request.getCutNo().isEmpty()) {
            return ResponseInfo.error("冲刀号不能为空", INPUT_ERROR.getCode());
        }
        /*写入数据*/
        request.setCompanyId(UserIdThread.get().getCompanyId());
        try {
            infoMapper.insert(request);
            /*处理重复*/
        } catch (Exception e) {     //用捕获的方法减少调用数据库
            if (e.getCause() instanceof SQLIntegrityConstraintViolationException) {
                return ResponseInfo.error("冲刀号重复", INPUT_ERROR.getCode());
            } else throw e;
        }
        return ResponseInfo.ok();
    }

    @Override
    public ResponseInfo cpCutUp(CpCutInfo request, String slipFlag, String cutNoOld) {
        /*入参检测*/
        if (slipFlag.equals("Y")) {
            return ResponseInfo.error("已入库，无法修改", INPUT_ERROR.getCode());
        }
        if (request.getCutNo() == null || request.getCutNo().isEmpty()) {
            return ResponseInfo.error("冲刀号不能为空", INPUT_ERROR.getCode());
        }
        /*更新数据*/
        LambdaUpdateWrapper<CpCutInfo> wrapper = new LambdaUpdateWrapper<CpCutInfo>()
                .eq(CpCutInfo::getCompanyId, UserIdThread.get().getCompanyId())
                .eq(CpCutInfo::getCutNo, cutNoOld)
                .set(request.getTechNote() == null || request.getTechNote().isEmpty(), CpCutInfo::getTechNote, null);
        try {
            infoMapper.update(request, wrapper);
            /*处理重复*/
        } catch (Exception e) {     //用捕获的方法减少调用数据库
            if (e.getCause() instanceof SQLIntegrityConstraintViolationException) {
                return ResponseInfo.error("冲刀号重复", INPUT_ERROR.getCode());
            } else throw e;
        }
        return ResponseInfo.ok();
    }

    @Override
    public ResponseInfo cpCutDel(String slipFlag, String cutNo) {
        /*入参检测*/
        if (slipFlag.equals("Y")) {
            return ResponseInfo.error("已入库，无法删除", INPUT_ERROR.getCode());
        }
        /*删除数据*/
        LambdaQueryWrapper<CpCutInfo> wrapper = new LambdaQueryWrapper<CpCutInfo>()
                .eq(CpCutInfo::getCompanyId, UserIdThread.get().getCompanyId())
                .eq(CpCutInfo::getCutNo, cutNo);
        infoMapper.delete(wrapper);
        return ResponseInfo.ok();
    }

    @Override
    public ResponseInfo getCpCutDetQuery(String cutNo) {
        /*获取数据*/
        List<Map<String, Object>> dtos = partMapper.getCpCutDetQuery(cutNo, UserIdThread.get().getCompanyId());
        return ResponseInfo.ok(dtos);
    }

    @Override
    public ResponseInfo cpCutDetAdd(CpCutPart request) {
        /*入参检测*/
        if (request.getPartName() == null || request.getPartName().isEmpty()) {
            return ResponseInfo.error("部位不能为空", INPUT_ERROR.getCode());
        }
        /*写入数据*/
        request.setCompanyId(UserIdThread.get().getCompanyId());
        try {
            partMapper.insert(request);
            /*处理重复*/
        } catch (Exception e) {     //用捕获的方法减少调用数据库
            if (e.getCause() instanceof SQLIntegrityConstraintViolationException) {
                return ResponseInfo.error("部位重复", INPUT_ERROR.getCode());
            } else throw e;
        }
        return ResponseInfo.ok();
    }

    @Override
    public ResponseInfo cpCutDetUp(CpCutPart request, String slipFlag, String cutNoOld, String partNameOld) {
        /*入参检测*/
        if (slipFlag.equals("Y")) {
            return ResponseInfo.error("已入库，无法修改", INPUT_ERROR.getCode());
        }
        if (request.getCutNo() == null || request.getCutNo().isEmpty()) {
            return ResponseInfo.error("部位不能为空", INPUT_ERROR.getCode());
        }
        /*更新数据*/
        LambdaUpdateWrapper<CpCutPart> wrapper = new LambdaUpdateWrapper<CpCutPart>()
                .eq(CpCutPart::getCompanyId, UserIdThread.get().getCompanyId())
                .eq(CpCutPart::getCutNo, cutNoOld)
                .eq(CpCutPart::getPartName, partNameOld)
                .set(request.getSeqNo() == null, CpCutPart::getSeqNo, null)
                .set(request.getSizeRegion() == null || request.getSizeRegion().isEmpty(), CpCutPart::getSizeRegion, null)
                .set(request.getRemark() == null || request.getRemark().isEmpty(), CpCutPart::getRemark, null);
        try {
            partMapper.update(request, wrapper);
            /*处理重复*/
        } catch (Exception e) {     //用捕获的方法减少调用数据库
            if (e.getCause() instanceof SQLIntegrityConstraintViolationException) {
                return ResponseInfo.error("部位重复", INPUT_ERROR.getCode());
            } else throw e;
        }
        return ResponseInfo.ok();
    }

    @Override
    public ResponseInfo cpCutDetDel(String slipFlag, String cutNo, String partName) {
        /*入参检测*/
        if (slipFlag.equals("Y")) {
            return ResponseInfo.error("已入库，无法修改", INPUT_ERROR.getCode());
        }
        /*删除数据*/
        LambdaQueryWrapper<CpCutPart> wrapper = new LambdaQueryWrapper<CpCutPart>()
                .eq(CpCutPart::getCompanyId, UserIdThread.get().getCompanyId())
                .eq(CpCutPart::getCutNo, cutNo)
                .eq(CpCutPart::getPartName, partName);
        partMapper.delete(wrapper);
        return ResponseInfo.ok();
    }

    @Override
    public ResponseInfo getCpCutStyleQuery(String cutNo) {
        /*获取数据*/
        LambdaQueryWrapper<CpCutStyle> wrapper = new LambdaQueryWrapper<CpCutStyle>()
                .eq(CpCutStyle::getCompanyId, UserIdThread.get().getCompanyId())
                .eq(CpCutStyle::getCutNo, cutNo);
        List<CpCutStyle> dtos = styleMapper.selectList(wrapper);
        return ResponseInfo.ok(dtos);
    }

    @Override
    public ResponseInfo cpCutStyleAdd(List<String> style, String cutNo) {
        /*入参检测*/
        if (style == null || style.isEmpty()) {
            return ResponseInfo.error("型体不能为空", INPUT_ERROR.getCode());
        }
        LambdaQueryWrapper<SdStyle> wrapper = new LambdaQueryWrapper<SdStyle>()
                .select(SdStyle::getStyleNo)
                .eq(SdStyle::getCompanyId, UserIdThread.get().getCompanyId())
                .in(SdStyle::getStyleNo, style);
        List<String> style1 = sdStyleMapper.selectList(wrapper)         //获取真实存在的型体集合
                .stream().map(SdStyle::getStyleNo).collect(Collectors.toList());
        if (style.size() == 1 && style1.size() < 1) {                      //只有一个型体的时候判断是否存在，否则不做提示，直接添加有效的型体
            return ResponseInfo.error("型体未建档");
        }
        style.retainAll(style1);               //保留有效型体
        LambdaQueryWrapper<CpCutStyle> styleWrapper = new LambdaQueryWrapper<CpCutStyle>()
                .select(CpCutStyle::getStyle)
                .eq(CpCutStyle::getCompanyId, UserIdThread.get().getCompanyId())
                .eq(CpCutStyle::getCutNo, cutNo)
                .in(CpCutStyle::getStyle, style);
        List<String> style2 = styleMapper.selectList(styleWrapper)              //找出重复的型体
                .stream().map(CpCutStyle::getStyle).collect(Collectors.toList());
        if (style.size() == 1 && style2.size() > 0) {
            return ResponseInfo.error("型体已存在", INPUT_ERROR.getCode());
        }
        style.removeAll(style2);               //去除重复型体
        /*写入数据*/
        CpCutStyle cutStyle = new CpCutStyle();
        cutStyle.setCompanyId(UserIdThread.get().getCompanyId());
        cutStyle.setCutNo(cutNo);
        for (String s : style) {
            cutStyle.setStyle(s);
            styleMapper.insert(cutStyle);
        }
        return ResponseInfo.ok();
    }

    @Override
    public ResponseInfo cpCutStyleUp(CpCutStyle request, String cutNoOld, String styleOld) {
        /*判断入参合法性*/
        if (request.getCutNo() == null || request.getCutNo().isEmpty()) {
            return ResponseInfo.error("部位不能为空", INPUT_ERROR.getCode());
        }
        LambdaQueryWrapper<SdStyle> sdWrapper = new LambdaQueryWrapper<SdStyle>()
                .eq(SdStyle::getCompanyId, UserIdThread.get().getCompanyId())
                .eq(SdStyle::getStyleNo, request.getStyle());
        Integer count = sdStyleMapper.selectCount(sdWrapper);
        if (count == 0) {
            return ResponseInfo.error("型体未建档", INPUT_ERROR.getCode());
        }
        /*更新数据*/
        LambdaUpdateWrapper<CpCutStyle> wrapper = new LambdaUpdateWrapper<CpCutStyle>()
                .eq(CpCutStyle::getCompanyId, UserIdThread.get().getCompanyId())
                .eq(CpCutStyle::getCutNo, cutNoOld)
                .eq(CpCutStyle::getStyle, styleOld);
        try {
            styleMapper.update(request, wrapper);
            /*处理重复*/
        } catch (Exception e) {     //用捕获的方法减少调用数据库
            if (e.getCause() instanceof SQLIntegrityConstraintViolationException) {
                return ResponseInfo.error("部位重复", INPUT_ERROR.getCode());
            } else throw e;
        }
        return ResponseInfo.ok();
    }

    @Override
    public ResponseInfo cpCutStyleDel(String cutNo, String style) {
        /*删除数据*/
        LambdaQueryWrapper<CpCutStyle> wrapper = new LambdaQueryWrapper<CpCutStyle>()
                .eq(CpCutStyle::getCompanyId, UserIdThread.get().getCompanyId())
                .eq(CpCutStyle::getCutNo, cutNo)
                .eq(CpCutStyle::getStyle, style);
        styleMapper.delete(wrapper);
        return ResponseInfo.ok();
    }

    @Override
    public void cutNoCheck(List<String> cutNoList) {
        /*不处理为空*/
        if (ArrayUtils.isNoEmpyt(cutNoList)){
            return;
        }
        Set<String> cutNoSet = new HashSet<>(cutNoList);
        /*判断是否存在*/
        LambdaQueryWrapper<CpCutInfo> wrapper = new LambdaQueryWrapper<CpCutInfo>()
                .select(CpCutInfo::getCutNo)
                .eq(CpCutInfo::getCompanyId, UserIdThread.get().getCompanyId())
                .in(CpCutInfo::getCutNo, cutNoSet)
                .groupBy(CpCutInfo::getCutNo);
        List<CpCutInfo> infos = infoMapper.selectList(wrapper);
        if (ArrayUtils.isEmpyt(infos)){
            throw new ServiceErrorException("冲刀号不存在");
        }
        /*去重*/
        infos.stream().map(CpCutInfo::getCutNo).collect(Collectors.toList()).forEach(cutNoSet::remove);
        if (ArrayUtils.isNoEmpyt(cutNoSet)){
            /*获取缺少的冲刀号*/
            String emptyCutNo = new ArrayList<>(cutNoSet).get(0);
            throw new ServiceErrorException("冲刀号:"+ emptyCutNo +"不存在");
        }
    }

    @Override
    public void cutNoCheck(String cutNo) {
        /*判断是否存在*/
        LambdaQueryWrapper<CpCutInfo> wrapper = new LambdaQueryWrapper<CpCutInfo>()
                .eq(CpCutInfo::getCompanyId, UserIdThread.get().getCompanyId())
                .eq(CpCutInfo::getCutNo, cutNo);
        if (infoMapper.selectCount(wrapper) == 0){
            throw new ServiceErrorException("冲刀号不存在");
        }
    }
}
